package com.aizuda.easyManagerTool.service.monitor.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.aizuda.easy.security.domain.Rep;
import com.aizuda.easy.security.domain.Req;
import com.aizuda.easyManagerTool.domain.dto.PageDTO;
import com.aizuda.easyManagerTool.domain.entity.monitor.MonitorDataEntity;
import com.aizuda.easyManagerTool.domain.entity.monitor.MonitorDataIndexEntity;
import com.aizuda.easyManagerTool.domain.entity.monitor.MonitorDataIndexItemEntity;
import com.aizuda.easyManagerTool.domain.vo.PageVO;
import com.aizuda.easyManagerTool.domain.vo.setting.SettingUserVO;
import com.aizuda.easyManagerTool.domain.vo.terminal.TreeIndexItemSelectVO;
import com.aizuda.easyManagerTool.domain.vo.terminal.TreeIndexItemVO;
import com.aizuda.easyManagerTool.mapper.monitor.MonitorDataIndexItemMapper;
import com.aizuda.easyManagerTool.mapper.monitor.MonitorDataIndexMapper;
import com.aizuda.easyManagerTool.service.monitor.MonitorDataIndexService;
import com.aizuda.easyManagerTool.util.AssertUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service
@Slf4j
public class MonitorDataIndexServiceImpl extends ServiceImpl<MonitorDataIndexItemMapper, MonitorDataIndexItemEntity> implements MonitorDataIndexService {

    @Resource
    MonitorDataIndexMapper monitorDataIndexMapper;
    @Resource
    MonitorDataIndexItemMapper monitorDataIndexItemMapper;
    @Resource
    MonitorListManagerService monitorListManagerService;

    @Override
    public Rep<PageVO<MonitorDataIndexEntity>> find(Req<PageDTO<MonitorDataIndexEntity>, SettingUserVO> req) {
        PageDTO<MonitorDataIndexEntity> pageDTO = req.getData();
        Page<MonitorDataIndexEntity> page = new Page<MonitorDataIndexEntity>(pageDTO.getCurrent(), pageDTO.getSize());
        // 查询 唯一条件是要根据 权限查询
        MonitorDataIndexEntity monitorDataIndexEntity = pageDTO.getData() ;
        IPage<MonitorDataIndexEntity> serverListEntrtyIPage = monitorDataIndexMapper.find(page, ObjectUtil.isEmpty(monitorDataIndexEntity)? new MonitorDataIndexEntity():monitorDataIndexEntity);
        PageVO<MonitorDataIndexEntity> pageVO = new PageVO<MonitorDataIndexEntity>(pageDTO)
                .setTotal(serverListEntrtyIPage.getTotal())
                .setRecords(serverListEntrtyIPage.getRecords());
        return Rep.ok(pageVO);
    }

    @Override
    public Rep<MonitorDataIndexEntity> edit(Req<MonitorDataIndexEntity, SettingUserVO> req) {
        MonitorDataIndexEntity data = req.getData();
        edit(data);
        return Rep.ok();
    }

    public void edit(MonitorDataIndexEntity data){
        AssertUtil.objIsNull(data.getMdId(),"数据错误");
        AssertUtil.objIsNull(data.getMdiTitle(),"标题不能为空");
        AssertUtil.objIsNull(data.getMdiThreshold(),"告警阈值不能为空");
        AssertUtil.objIsNull(data.getMdiAlarm(),"开启告警不能为空");
        AssertUtil.objIsNull(data.getMdiFrequency(),"连续次数不能为空");
        AssertUtil.objIsNull(data.getExps(),"请增加至少一个指标" );
        if(data.getExps().size() < 1){
            Rep.error(500,"请增加至少一个指标");
        }
        data.getExps().forEach(item -> item.setMdId(data.getMdId()));
        if(ObjectUtil.isNotEmpty(data.getId())){
            monitorDataIndexMapper.updateById(data);
        }else{
            monitorDataIndexMapper.insert(data);
        }
        for (MonitorDataIndexItemEntity exp : data.getExps()) {
            exp.setMdiId(data.getId());
            exp.setTenantId(data.getTenantId());
        }
        if(CollUtil.isNotEmpty(data.getExps()) && data.getExps().size() > 0) {
            saveOrUpdateBatch(data.getExps());
        }
        monitorListManagerService.updateMonitorData(data.getMdId());
    }

    @Transactional
    @Override
    public Rep<MonitorDataIndexEntity> del(Req<MonitorDataIndexEntity, SettingUserVO> req) {
        MonitorDataIndexEntity data = req.getData();
        AssertUtil.objIsNull(data.getId(),"数据错误");
        monitorListManagerService.delMonitorDataIndex(data.getId());
        monitorDataIndexMapper.deleteById(data.getId());
        monitorDataIndexItemMapper.deleteByMdiId(data.getId());
        return Rep.ok();
    }

    @Override
    public Rep<MonitorDataIndexItemEntity> delIndexItem(Req<MonitorDataIndexItemEntity, SettingUserVO> req) {
        MonitorDataIndexItemEntity data = req.getData();
        AssertUtil.objIsNull(data.getId(),"数据错误");
        monitorDataIndexItemMapper.deleteById(data.getId());
        MonitorListManager.removeIndex(data.getId());
        return Rep.ok();
    }

    @Override
    public Rep<List<MonitorDataIndexItemEntity>> findIndexItem(Req<MonitorDataIndexItemEntity, SettingUserVO> req) {
        MonitorDataIndexItemEntity data = req.getData();
        AssertUtil.objIsNull(data.getMdiId(), "数据错误");
        List<MonitorDataIndexItemEntity> m = monitorDataIndexItemMapper.find(data.getMdiId());
        return Rep.ok(m);
    }

    @Override
    public Rep<MonitorDataIndexItemEntity> editIndexItem(Req<MonitorDataIndexItemEntity, SettingUserVO> req) {
        MonitorDataIndexItemEntity data = req.getData();
        editIndexItem(data);
        return Rep.ok(data);
    }

    public void editIndexItem(MonitorDataIndexItemEntity data){
        AssertUtil.objIsNull(data.getMdiiName(),"名称不能为空");
        AssertUtil.objIsNull(data.getMdiiExp(),"表达式不能为空");
        AssertUtil.objIsNull(data.getId(),"数据错误");
        AssertUtil.objIsNull(data.getMdiId(),"数据错误");
        monitorDataIndexItemMapper.updateById(data);
        monitorListManagerService.updateMonitorDataIndex(data.getId());
    }

    @Override
    public Rep<List<TreeIndexItemVO>> treeIndexItem(Req<MonitorDataEntity, SettingUserVO> req) {
        List<TreeIndexItemSelectVO> treeIndexItemSelectVOS = monitorDataIndexMapper.selectTreeIndex();
        List<TreeIndexItemVO> treeIndexItemVOS = new ArrayList<>();
        generateTree(treeIndexItemSelectVOS,treeIndexItemVOS);
        return Rep.ok(treeIndexItemVOS);
    }

    @Override
    public Rep<MonitorDataIndexEntity> editIndexAlarm(Req<MonitorDataIndexEntity, SettingUserVO> req) {
        MonitorDataIndexEntity data = req.getData();
        monitorDataIndexMapper.updateById(data);
        monitorListManagerService.updateMonitorDataIndex(data.getId());
        return Rep.ok();
    }

    private void generateTree(List<TreeIndexItemSelectVO> treeIndexItemSelectVOS,List<TreeIndexItemVO> treeIndexItemVOS){
        treeIndexItemSelectVOS.forEach(item -> {
            String key = item.getId() + ":" + item.getMdTitle();
            Optional<TreeIndexItemVO> any = treeIndexItemVOS.stream().filter(i -> i.getId().equals(key)).findAny();
            if (any.isPresent()) {
                return;
            }
            TreeIndexItemVO treeIndexItemVO = new TreeIndexItemVO();
            treeIndexItemVO.setId(key);
            treeIndexItemVO.setLabel(item.getMdTitle());
            generateMdiTree(treeIndexItemVO,treeIndexItemSelectVOS);
            treeIndexItemVOS.add(treeIndexItemVO);
        });
    }

    private void generateMdiTree(TreeIndexItemVO mdi,List<TreeIndexItemSelectVO> treeIndexItemSelectVOS){
        treeIndexItemSelectVOS.stream().filter(item -> (item.getId() + ":" + item.getMdTitle()) .equals(mdi.getId())).forEach(item -> {
            if(ObjectUtil.isEmpty(item.getTmdiId())){
                return;
            }
            String key = item.getTmdiId() + ":" + item.getMdiTitle();
            Optional<TreeIndexItemVO> any = mdi.getChildren().stream().filter(i -> i.getId().equals(key)).findAny();
            if (any.isPresent()) {
                return;
            }
            TreeIndexItemVO treeIndexItemVO = new TreeIndexItemVO();
            treeIndexItemVO.setId(key);
            treeIndexItemVO.setLabel(item.getMdiTitle());
            generateMdiITree(treeIndexItemVO,treeIndexItemSelectVOS);
            mdi.getChildren().add(treeIndexItemVO);
        });
    }

    private void generateMdiITree(TreeIndexItemVO mdii,List<TreeIndexItemSelectVO> treeIndexItemSelectVOS){
        treeIndexItemSelectVOS.stream().filter(item -> (item.getTmdiId() + ":" + item.getMdiTitle()).equals(mdii.getId())).forEach(item -> {
            Optional<TreeIndexItemVO> any = mdii.getChildren().stream().filter(i -> i.getId().equals(item.getTmdiiId().toString())).findAny();
            if (any.isPresent()) {
                return;
            }
            if(ObjectUtil.isNotEmpty(item)) {
                TreeIndexItemVO treeIndexItemVO = new TreeIndexItemVO();
                treeIndexItemVO.setId(item.getTmdiiId().toString());
                treeIndexItemVO.setLabel(item.getMdiiName());
                mdii.getChildren().add(treeIndexItemVO);
            }
        });
    }

}
